package com.wyy.service.impl;

import com.alibaba.fastjson.JSON;
import com.wyy.error.BusinessException;
import com.wyy.error.EnumBusinessError;
import com.wyy.mapper.ArticleMapper;
import com.wyy.mapper.UserMapper;
import com.wyy.pojo.Articles;
import com.wyy.pojo.LikeArticle;
import com.wyy.pojo.model.ArticleModel;
import com.wyy.pojo.model.ArticleQueryCriteria;
import com.wyy.pojo.model.LabelSearch;
import com.wyy.pojo.model.UserToken;
import com.wyy.service.ArticleService;
import com.wyy.util.MyUtil;
import com.wyy.util.TokenUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: gytcb
 * @author: 吴磊
 * @create: 2021-06-03 20:21
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    private UserMapper userMapper;


    private MyUtil myUtil = new MyUtil();

    /**
     * 获取热门的文章标签
     *
     * @return
     */
    @Override
    public Map<String, Object> getHotArticleLabel() {
        List<LabelSearch> hotArticleLabel = articleMapper.getHotArticleLabel();
        HashMap<String, Object> map = new HashMap<>();
        map.put("labels", hotArticleLabel);
        return map;
    }

    /**
     * 根据文章内容模糊查询文章
     * 如果userId为空就说明是查询全部
     *
     * @param articles
     * @return
     */
    @Override
    public Map<String, Object> getArticleByArticleContentLikeSearch(Articles articles) {
        String articleContent = articles.getArticleContent();
        articleContent = "%" + articleContent + "%";
        articles.setArticleContent(articleContent);
        int totalCount = articleMapper.getCountByArticleContent(articles);
        List<Articles> articlesList = articleMapper.getArticleByArticleContentLikeSearch(articles);
        HashMap<String, Object> map = new HashMap<>();
        List<ArticleModel> articleModels = convertToArticleModel(articlesList);
        map.put("articles", articleModels);
        map.put("total", totalCount);
        return map;
    }

    /**
     * 根据文章Id获取文章
     *
     * @param articles
     * @return
     */
    @Override
    public Map<String, Object> getArticleByArticleId(Articles articles) {
        String id = articles.getArticleId();
        //查询文章
        Articles article = articleMapper.getArticleByArticleId(id);
        ArrayList<Articles> objects = new ArrayList<>();
        objects.add(article);
        List<ArticleModel> articleModels = convertToArticleModel(objects);
        HashMap<String, Object> map = new HashMap<>();
        map.put("article", articleModels);
        return map;
    }

    @Override
    public void insertArticle(Articles articles) {
        UserToken userToken = tokenUtils.parseTokenToUserToken();
        String articleId = myUtil.getUUID();
        String articleDate = myUtil.getCurrentDetailedTime();
        if (StringUtils.isEmpty(articles.getArticleTitle())) {
            articles.setArticleTitle("");
        }
        if (StringUtils.isEmpty(articles.getArticleLabel())) {
            articles.setArticleLabel("");
        }
        articles.setArticleId(articleId);
        articles.setArticleDate(articleDate);
        articles.setUserId(userToken.getUserId());
        Integer i = articleMapper.insertArticle(articles);
        if (i <= 0) {
            throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "帖子发布失败");
        }
    }

    @Override
    public void deleteArticleByArticleId(String articleId) {
        String id = JSON.parseObject(articleId, Articles.class).getArticleId();
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException(EnumBusinessError.PARAMETER_INVALID_ERROR);
        }
        Integer integer = articleMapper.deleteArticleById(id);
        if (integer <= 0) {
            throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "帖子删除失败（不要重复此操作）");
        }
    }

    @Override
    public void updateArticle(Articles articles) {
        UserToken loginUser = tokenUtils.parseTokenToUserToken();
        if (!loginUser.getUserId().equals(articles.getUserId())) {
            throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "前端处理，这是最后一个验证，本帖子不是当前用户所属");
        }
        if (StringUtils.isEmpty(articles.getArticleTitle())) {
            articles.setArticleTitle("");
        }
        if (StringUtils.isEmpty(articles.getArticleLabel())) {
            articles.setArticleLabel("");
        }
        Integer integer = articleMapper.updateArticle(articles);
        if (integer <= 0) {
            throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "帖子编辑失败");
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void likeOrCancelLikeArticle(LikeArticle likeArticle) {
        Integer i = articleMapper.getLikeArticleByUserIdAndArticleId(likeArticle);
        if (i <= 0) {
            //点赞
            Integer integer = articleMapper.insertLikeArticle(likeArticle);
            if (integer <= 0) {
                throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "点赞失败");
            }
            articleMapper.incrArticleLikeCount(likeArticle.getArticleId());
        } else {
            //取消点赞
            Integer integer = articleMapper.deleteLikeArticle(likeArticle);
            if (integer <= 0) {
                throw new BusinessException(EnumBusinessError.UNKNOWN_ERROR, "取消点赞失败");
            }
            articleMapper.decrArticleLikeCount(likeArticle.getArticleId());
        }
    }

    @Override
    public Map<String, Object> getArticleBySomething(ArticleQueryCriteria articleQueryCriteria) {
        /**
         * 先说明情况
         * 1、用户首页查看文章
         * 2、用户通过文章评论查看文章
         */
        HashMap<String, Object> map = new HashMap<>();
        List<Articles> articles = null;
        String type = articleQueryCriteria.getType();
        String userId = articleQueryCriteria.getUserId();
        int curPage = articleQueryCriteria.getCurPage();
        if (curPage <= 0) {
            curPage = 1;
        }
        int totalCount = 0;
        int totalPage = 0;
        if ("hot".equals(type)) {
            //热门文章
            totalCount = articleMapper.getArticleCount(null);
            totalPage = (totalCount + 20 - 1) / 20;
            if (totalPage <= 0) {
                map.put("totalCount", 0);
                map.put("totalPage", 0);
                map.put("articles", new ArrayList<>());
                return map;
            }
            if (curPage > totalPage) {
                curPage = totalPage;
            }
            articles = articleMapper.getArticleByHot((curPage - 1) * 20);
        } else if ("latest".equals(type)) {
            if (StringUtils.isEmpty(userId)) {
                //用户Id为空，说明查询的就是最新的文章
                totalCount = articleMapper.getArticleCount(null);
                totalPage = (totalCount + 20 - 1) / 20;
                if (totalPage <= 0) {
                    map.put("totalCount", 0);
                    map.put("totalPage", 0);
                    map.put("articles", new ArrayList<>());
                    return map;
                }
                if (curPage > totalPage) {
                    curPage = totalPage;
                }
                articles = articleMapper.getArticleByLatest((curPage - 1) * 20, null);
            } else {
                //根据用户Id查询文章
                /**
                 * 在这里要判断情况了，用户是否登录，是否是用户自己
                 */
                boolean flag = false;
                String isLogin = tokenUtils.parseTokenToken();
                if (!StringUtils.isEmpty(isLogin)) {
                    //用户登录了，接下来要判断是否是自己本人，如果不是，则隐藏匿名的文章
                    UserToken loginUser = tokenUtils.getInfoFromToken(isLogin);
                    String loginUserId = loginUser.getUserId();
                    if (loginUserId.equals(userId)) {
                        flag = true;
                        //是用户本人
                        totalCount = articleMapper.getArticleCount(userId);
                        totalPage = (totalCount + 20 - 1) / 20;
                        if (curPage > totalPage) {
                            curPage = totalPage;
                        }
                        articles = articleMapper.getArticleByLatest((curPage - 1) * 20, userId);
                    }
                }
                if (!flag) {
                    //获取用户没有匿名的数量
                    totalCount = articleMapper.getArticleCountNot(userId);
                    totalPage = (totalCount + 20 - 1) / 20;
                    if (totalPage <= 0) {
                        map.put("totalCount", 0);
                        map.put("totalPage", 0);
                        map.put("articles", new ArrayList<>());
                        return map;
                    }
                    if (curPage > totalPage) {
                        curPage = totalPage;
                    }
                    articles = articleMapper.getArticleByLatestNot((curPage - 1) * 20, userId);
                }
            }
        } else {
            //按时间段
            Date nowDate = new Date();
            int creamTime = Integer.parseInt(type.split("-")[1]);
            long time = nowDate.getTime() - (1000L * 60 * 60 * creamTime);
            String timeToString = MyUtil.parseTimeToString(new Date(time));
            totalCount = articleMapper.getArticleCountByCream(timeToString);
            totalPage = (totalCount + 20 - 1) / 20;
            if (totalPage <= 0) {
                map.put("totalCount", 0);
                map.put("totalPage", 0);
                map.put("articles", new ArrayList<>());
                return map;
            }
            if (curPage > totalPage) {
                curPage = totalPage;
            }
            articles = articleMapper.getArticleByCream(timeToString, (curPage - 1) * 20);
        }

        List<ArticleModel> articleModels = convertToArticleModel(articles);
        map.put("totalCount", totalCount);
        map.put("totalPage", totalPage);
        map.put("articles", articleModels);
        return map;
    }

    @Override
    public Map<String, Object> getArticleBySearchLabel(LabelSearch labelSearch) {
        HashMap<String, Object> map = new HashMap<>();
        String articleLabel = labelSearch.getArticleLabel();
        int curPage = labelSearch.getCurPage();
        if (curPage <= 0) {
            curPage = 1;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("%");
        for (int i = 0; i < articleLabel.length(); i++) {
            sb.append(articleLabel.charAt(i));
            sb.append("%");
        }
        String likeLabel = sb.toString();
        //获取模糊查询的总文章数
        Integer totalCount = articleMapper.getArticleBySearchLabelCount(likeLabel);
        //计算总页数
        int totalPage = (totalCount + 20 - 1) / 20;
        if (totalPage <= 0) {
            map.put("totalCount", 0);
            map.put("totalPage", 0);
            map.put("articles", new ArrayList<>());
            return map;
        }
        if (curPage > totalPage) {
            curPage = totalPage;
        }
        //查出所有的模糊文章
        List<Articles> articles = articleMapper.getArticleBySearchLabel(likeLabel, (curPage - 1) * 20);
        //处理文章为ArticleModel
        List<ArticleModel> articleModels = convertToArticleModel(articles);

        map.put("totalCount", totalCount);
        map.put("totalPage", totalPage);
        map.put("articles", articleModels);
        return map;
    }

    /**
     * 将查出来的文章处理为ArticleModel
     *
     * @param articles
     * @return
     */
    private List<ArticleModel> convertToArticleModel(List<Articles> articles) {
        List<ArticleModel> articleModels = articles.stream().map(article -> {
            ArticleModel articleModel = new ArticleModel();
            BeanUtils.copyProperties(article, articleModel);
            String articleUserId = article.getUserId();
            UserToken articleUser = userMapper.getUserById(articleUserId);
            if ("1".equals("" + article.getArticleStatus())) {
                articleModel.setUserToken(articleUser);
            } else {
                UserToken userToken = new UserToken(articleUser.getUserId(), "匿名", "http://www.6our.com/Public/face/f_noface.png", "");
                articleModel.setUserToken(userToken);
            }
            String token = tokenUtils.parseTokenToken();
            if (StringUtils.isEmpty(token)) {
                //用户没登录
                articleModel.setOwner(false);
                articleModel.setLike(false);
            } else {
                UserToken loginUser = tokenUtils.getInfoFromToken(token);
                String loginUserId = loginUser.getUserId();
                if (loginUserId.equals(articleUserId)) {
                    articleModel.setOwner(true);
                } else {
                    articleModel.setOwner(false);
                }
                LikeArticle likeArticle = new LikeArticle(loginUserId, article.getArticleId());
                Integer i = articleMapper.getLikeArticleByUserIdAndArticleId(likeArticle);
                if (i <= 0) {
                    articleModel.setLike(false);
                } else {
                    articleModel.setLike(true);
                }
            }
            return articleModel;
        }).collect(Collectors.toList());
        return articleModels;
    }
}
